/**
 * 
 */
package org.statewalker.validator;

import org.statewalker.dict.BaseDict;

public abstract class AbstractGrammar {

    private final ValidatorGrammarConfig fConfig;

    private String fRoot;

    public AbstractGrammar(ValidatorGrammarConfig config) {
        this(config, null);
    }

    public AbstractGrammar(ValidatorGrammarConfig config, String root) {
        fRoot = root != null ? root : BaseDict.ROOT;
        fConfig = config;
        defineParent(BaseDict.INITIAL, getROOT());
        defineParent(BaseDict.FINAL, getROOT());
    }

    protected void defineMandatoryTransition(String key, String from, String to) {
        fConfig.beginState(key);
        fConfig.onTransition(from, BaseDict.ANY, to);
        fConfig.onTransition(from, BaseDict.FINAL, to);
        fConfig.endState();
    }

    protected void defineParent(String child, String parent) {
        fConfig.setParentToken(child, parent);
    }

    protected void defineSubstates(String key, String... children) {
        fConfig.beginState(key);
        for (String child : children) {
            fConfig.onDefaultTransition(child, child);
        }
        fConfig.endState();
    }

    protected void defineTransition(
        String key,
        String entityKey,
        String targetKey) {
        fConfig.beginState(key);
        fConfig.onDefaultTransition(entityKey, targetKey);
        fConfig.endState();
    }

    protected void defineTransition(
        String key,
        String from,
        String entity,
        String to) {
        fConfig.beginState(key);
        fConfig.onTransition(from, entity, to);
        fConfig.endState();
    }

    public ValidatorGrammarConfig getConfig() {
        return fConfig;
    }

    public String getROOT() {
        return fRoot;
    }

    public abstract void init();

    protected String init(String key) {
        fConfig.beginState(key);
        fConfig.onDefaultTransition(BaseDict.FINAL, BaseDict.FINAL);
        fConfig.endState();
        return key;
    }

    protected void markAsLeaf(String state) {
        fConfig.markAsLeaf(state);
    }

}